import type { UserInfo } from '@/types/user'
import type { Permission } from '@/types/rbac'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { getUserInfoApi, loginApi, refreshTokenApi, registerApi } from '@/api/user'
import { HttpStatus } from '@/api/types'
import router from '@/router'

export const useUserStore = defineStore('user', () => {
  // 初始化时从本地存储中读取 token
  const token = ref<string | null>(localStorage.getItem('token') || sessionStorage.getItem('token'))
  const tokenRefresh = ref<string | null>(
    localStorage.getItem('refresh_token') || sessionStorage.getItem('refresh_token'),
  )

  async function refreshToken() {
    if (!tokenRefresh.value) {
      throw new Error('No refresh token available')
    }
    try {
      const response = await refreshTokenApi(tokenRefresh.value)
      if (response.statusCode === HttpStatus.OK && response.data?.access_token) {
        setToken(response.data?.access_token)
      } else {
        throw new Error('Refresh token failed')
      }
    } catch (error) {
      throw error
    }
  }

  const remember = computed(() => {
    return localStorage.getItem('remember') === 'true'
  })

  function setRemember(newRemember: boolean) {
    localStorage.setItem('remember', newRemember.toString())
  }

  // 初始化时从本地存储中读取用户信息
  const userInfo = ref<UserInfo | null>(
    JSON.parse(localStorage.getItem('userInfo') || sessionStorage.getItem('userInfo') || 'null'),
  )

  const routesLoaded = ref(false)

  const permissions = ref<Permission[] | null>(null)

  function setPermissions(newPermissions: Permission[] | null) {
    permissions.value = newPermissions
  }

  function setToken(newToken: string) {
    token.value = newToken
    if (remember.value) {
      localStorage.setItem('token', newToken)
      sessionStorage.removeItem('token')
    } else {
      sessionStorage.setItem('token', newToken)
      localStorage.removeItem('token')
    }
  }

  function setRefreshToken(newToken: string) {
    tokenRefresh.value = newToken
    if (remember.value) {
      localStorage.setItem('refresh_token', newToken)
      sessionStorage.removeItem('refresh_token')
    } else {
      sessionStorage.setItem('refresh_token', newToken)
      localStorage.removeItem('refresh_token')
    }
  }

  async function getUserInfo() {
    if (!token.value) {
      throw new Error('No token available')
    }
    try {
      const response = await getUserInfoApi()
      setUserInfo(response)
    } catch (error) {
      throw error
    }
  }

  function setUserInfo(info: UserInfo) {
    userInfo.value = info
    const userInfoStr = JSON.stringify(info)
    if (remember.value) {
      localStorage.setItem('userInfo', userInfoStr)
      sessionStorage.removeItem('userInfo')
    } else {
      sessionStorage.setItem('userInfo', userInfoStr)
      localStorage.removeItem('userInfo')
    }
  }

  function setRoutesLoaded(loaded: boolean) {
    routesLoaded.value = loaded
  }

  const isLoggedIn = computed(() => {
    return token.value !== null || tokenRefresh.value !== null
  })

  async function login(
    usernameOrEmail: string,
    password: string,
    captcha: string,
    captchaId: string,
    remember = false,
  ) {
    const res = await loginApi({
      usernameOrEmail,
      password,
      captcha,
      captchaId,
    })
    if (res.statusCode === HttpStatus.OK && res.data) {
      setRemember(remember)
      setToken(res.data.access_token)
      setRefreshToken(res.data.refresh_token)
      setUserInfo(res.data.user as UserInfo)
      return {
        success: true,
        data: res.data,
      }
    } else {
      return {
        success: false,
        message: res.message,
      }
    }
  }

  async function register(
    username: string,
    email: string,
    password: string,
    confirmPassword: string,
    captcha: string,
    captchaId: string,
  ) {
    if (!username || !email || !password || !confirmPassword || !captcha) {
      return {
        success: false,
        message: '请填写完整信息',
      }
    }

    if (password !== confirmPassword) {
      return {
        success: false,
        message: '两次输入的密码不一致',
      }
    }

    try {
      const res = await registerApi({
        username,
        email,
        password,
        captcha,
        captchaId,
      })

      if (res.statusCode === HttpStatus.OK && res.data) {
        return {
          success: true,
          message: '注册成功，请登录！',
          data: res.data,
        }
      } else {
        return {
          success: false,
          message: typeof res.message === 'string' ? res.message : '注册失败，请重试',
        }
      }
    } catch (e: unknown) {
      return {
        success: false,
        message:
          typeof (e as { message?: string })?.message === 'string'
            ? (e as { message: string }).message
            : '注册失败，请稍后重试',
      }
    }
  }

  function logout() {
    token.value = null
    tokenRefresh.value = null
    userInfo.value = null
    routesLoaded.value = false
    // 清除本地存储中的数据
    localStorage.removeItem('token')
    localStorage.removeItem('refresh_token')
    localStorage.removeItem('userInfo')
    sessionStorage.removeItem('token')
    sessionStorage.removeItem('refresh_token')
    sessionStorage.removeItem('userInfo')
    router.push('/login')
  }

  return {
    token,
    tokenRefresh,
    userInfo,
    routesLoaded,
    isLoggedIn,
    permissions,
    setPermissions,
    setToken,
    refreshToken,
    setRefreshToken,
    getUserInfo,
    setUserInfo,
    setRoutesLoaded,
    login,
    register,
    logout,
    setRemember,
    remember,
  }
})

export default useUserStore
